﻿using HARTCalibrationTool.SerialPortManager;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Channels;
using System.Text;
using System.Threading.Tasks;

namespace HARTCalibrationTool.Commands.HART
{
    public class HART2ReadLoopCurrentAndPerOfRge : HARTCMDsBase
    {
        public HART2ReadLoopCurrentAndPerOfRge(SerialPortsBase serialPortManager, string commandName) : base(serialPortManager, commandName)
        {
            _stHARTCMDsStruct = new HARTCMDsCodeStruct()
            {
                preamble = new byte[5] { 0xff, 0xff, 0xff, 0xff, 0xff },
                start = 0x82,
                addressByte1 = 0xA2,
                addressByte2 = 0x82,
                addressByte3 = 0x74,
                addressByte4 = 0x2E,
                addressByte5 = 0x96,
                cmdID = 0x02,
                size = 0x00,
                parity = 0xFF,
            };
        }

        protected override async Task SendCMD()
        {
            byte[] deviceID = GetDeviceID();
            byte[] cmdCode = null;
            byte[] tempData = new byte[32];

            if ((deviceID[0] == 0x00) && (deviceID[1] == 0x00) && (deviceID[2] == 0x00))
            {
                SerialPortsBase.PrintMessage("通道" + Utils.CountTrailingZeros((uint)GetCMDsChannelID()).ToString() + ", Device ID 错误！");
                return;
            }

            _stHARTCMDsStruct.addressByte3 = deviceID[0];
            _stHARTCMDsStruct.addressByte4 = deviceID[1];
            _stHARTCMDsStruct.addressByte5 = deviceID[2];

            cmdCode = StructToBytes<HARTCMDsCodeStruct>(_stHARTCMDsStruct);

            Array.Copy(cmdCode, 5, tempData, 0, 8);
            cmdCode[cmdCode.Length - 1] = Utils.GetHARTCRC(tempData, 8);

            SerialPortsBase.PrintMessage("--> " + Utils.HexToString(cmdCode));

            await SerialPortMager.SerialPortWrite(cmdCode);
        }

        public override async Task ParseResponse(byte[] data)
        {
            List<string> parts = new List<string>();
            byte[] bytes = Utils.GetHARTDataFrame(data);
            byte[] pvBytes = new byte[4];
            string channel = ((byte)CurrentGroupChannel - 1).ToString();

            Array.Copy(bytes, 10, pvBytes, 0, 4);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(pvBytes);
            }

            await Task.Run(() =>
            {
                parts.Add(channel + "#Current: " + (BitConverter.ToSingle(pvBytes, 0)).ToString("F4"));
                SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #2 Read Current"], parts);

                parts.Clear();
                parts.Add(channel + "#" + (BitConverter.ToSingle(pvBytes, 0)).ToString("F4") + " mA");
                SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #2 Show Current"], parts);

                SerialPortsBase.PrintMessage("<-- " + $"{Utils.HexToString(data)}");
            });
        }

        public override void OnFailure()
        {

        }

        public override void OnSuccess()
        {

        }

        public override void OnTimeout()
        {

        }
    }

    public class HART2ReadLoopCurrentAndPerOfRgeForRetest : HART2ReadLoopCurrentAndPerOfRge
    {
        public HART2ReadLoopCurrentAndPerOfRgeForRetest(SerialPortsBase serialPortManager, string commandName) : base(serialPortManager, commandName)
        { 
        
        }

        public override async Task ParseResponse(byte[] data)
        { 
            await base.ParseResponse(data);

            List<string> parts = new List<string>();
            byte[] bytes = Utils.GetHARTDataFrame(data);
            byte[] pvBytes = new byte[4];
            string channel = ((byte)CurrentGroupChannel - 1).ToString();

            Array.Copy(bytes, 10, pvBytes, 0, 4);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(pvBytes);
            }

            parts.Add(channel + "#Current#" + (BitConverter.ToSingle(pvBytes, 0)).ToString("F4"));
            SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #2 Read Current Retest"], parts);
        }
    }

    public class RetestHART2ReadLoopCurrent : HART2ReadLoopCurrentAndPerOfRge
    {
        public static string upOrDown = null;

        public RetestHART2ReadLoopCurrent(SerialPortsBase serialPortManager, string commandName) : base(serialPortManager, commandName)
        {

        }

        static RetestHART2ReadLoopCurrent()
        {
            upOrDown = "Up";
        }

        public override async Task ParseResponse(byte[] data)
        {
            await base.ParseResponse(data);

            CommandExeSuccess();
            SetCurrentCMDResponseFinishedFlg();

            await Task.Run(() =>
            {
                List<string> parts = new List<string>();
                byte[] bytes = Utils.GetHARTDataFrame(data);
                byte[] pvBytes = new byte[4];
                string channel = ((byte)CurrentGroupChannel - 1).ToString();

                Array.Copy(bytes, 10, pvBytes, 0, 4);

                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(pvBytes);
                }

                parts.Add(channel + "#Current#" + upOrDown + "#" + (BitConverter.ToSingle(pvBytes, 0)).ToString("F4"));
                SerialPortMager.NotifyObserver(HARTObserversInfo.info["HART #2 Read Current Excel"], parts);
            });
        }
    }
}
